/*
 * Copyright (c) 2010, kamaboco <kamaboco@gmail.com>.
 * 
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * 
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * 
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 
 * 3. This notice may not be removed or altered from any source
 * distribution.
 */
module dnkf_internal;

import nkf;
import core.stdc.string;
import core.stdc.stdio;

private
{

string optionData = null;

const(char)[] inputData = null;
uint inputIndex = 0;

char[] outputData = null;
//uint outputIndex = 0;

} // private


extern (C)
{

void dnkf_internal_throw(in char *msg)
{
    throw new NkfException(msg[0 .. strlen(msg)].idup);
}


void* dnkf_internal_malloc(size_t size)
{
    if (size == 0) size = 1;
    
    return (new void[size]).ptr;
}

void* dnkf_internal_realloc(void *ptr, size_t size)
{
    if (size == 0) size = 1;
    
    if (ptr)
    {
        auto a = ptr[0 .. size];
        a.length = size;
        return a.ptr;
    }
    else
    {
        return dnkf_internal_malloc(size);
    }
}

void dnkf_internal_free(void *ptr)
{
    delete ptr;
}


void dnkf_internal_input_clear()
{
    inputData = null;
    inputIndex = 0;
}

void dnkf_internal_input_set_buffer(const (void) *bufStr, size_t bufLen)
{
    inputData = cast(const(char)[])bufStr[0 .. bufLen];
    inputIndex = 0;
}

void dnkf_internal_output_clear()
{
    outputData = null;
}

const(char)[] dnkf_internal_output_get()
{
    return outputData;
}


int dnkf_internal_getc()
{
    if (inputIndex < inputData.length)
    {
        return inputData[inputIndex++];
    }
    else
    {
        return EOF;
    }
}

void dnkf_internal_putc(int c)
{
    if (c!=EOF)
    {
        outputData ~= cast(char)c;
    }
}


string dnkf_get_option()
{
    return optionData;
}

int dnkf_set_option(immutable(char)* optStr, size_t optLen)
{
    if (optStr)
    {
        optionData = optStr[0 .. optLen];
        
        if (optLen > 0 && optStr[optLen-1] != '\0')
        {
            optionData ~= '\0';
        }
    }
    else
    {
        optionData = null;
    }
    
    return 0;
}

}
